package com.hhkj.admin.course.service.biz.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.hhkj.admin.bank.domain.Bank;
import com.hhkj.admin.bank.domain.BankRule;
import com.hhkj.admin.bank.service.base.BankRuleService;
import com.hhkj.admin.bank.service.base.BankService;
import com.hhkj.admin.course.common.component.checker.CourseBankTypeChecker;
import com.hhkj.admin.course.common.cont.CourseConst;
import com.hhkj.admin.course.domain.Course;
import com.hhkj.admin.course.domain.CourseBankType;
import com.hhkj.admin.course.model.dopo.CourseBankTypeDo;
import com.hhkj.admin.course.model.dopo.CourseBankTypePo;
import com.hhkj.admin.course.model.req.CourseBankTypeReq;
import com.hhkj.admin.course.model.res.CourseBankTypeRes;
import com.hhkj.admin.course.service.base.CourseBankTypeService;
import com.hhkj.admin.course.service.biz.CourseBankTypeBizService;
import com.hhkj.admin.course.service.extend.CourseBankTypeExtendService;
import com.hhkj.admin.course.service.extend.CourseExtendService;
import com.hhkj.admin.student.domain.StudentCourse;
import com.hhkj.admin.student.service.base.StudentCourseService;
import com.ruoyi.common.base.biz.service.biz.BaseBizServiceImpl;
import com.ruoyi.common.cont.SysConst;
import com.ruoyi.common.exception.GlobalException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * CourseBankTypeBizServiceImpl
 *
 * @author HHKJ-SERVER-ZJ
 * @since 2023/6/8 10:38
 */
@Service
public class CourseBankTypeBizServiceImpl
        extends BaseBizServiceImpl<CourseBankType, CourseBankTypeReq, CourseBankTypeRes,
        CourseBankTypeDo, CourseBankTypePo, CourseBankTypeService, CourseBankTypeExtendService>
        implements CourseBankTypeBizService
{
    @Autowired
    private CourseExtendService courseExtendService;
    @Autowired
    private BankService bankService;
    @Autowired
    private BankRuleService bankRuleService;
    @Lazy
    @Autowired
    private StudentCourseService studentCourseService;
    @Autowired
    private CourseBankTypeChecker checker;

    @Override
    public boolean updateDefaultFlag(CourseBankTypeReq req) {
        CourseBankTypePo courseBankTypePo = null;
        //判断是否是默认题库
        if (CourseConst.DefaultBank.DEFAULT.getCode().equals(req.getDefaultFlag())) {
            courseBankTypePo = getService().getPoById(req.getId());
            if (ObjectUtil.isEmpty(courseBankTypePo)) {
                throw new GlobalException("题库类型不存在");
            }
            if(SysConst.Flag.IS.getFlag().equals(courseBankTypePo.getDisableFlag())) {
                throw new GlobalException("题库已被禁用，无法设置默认题库");
            }
            LambdaUpdateWrapper<CourseBankType> updateWrapper = new LambdaUpdateWrapper<CourseBankType>()
                    .eq(CourseBankType::getCourseId, courseBankTypePo.getCourseId())
                    .set(CourseBankType::getDefaultFlag, CourseConst.DefaultBank.NORMAL.getCode());
            this.getService().update(updateWrapper);
        } else {
            return true;
        }
        LambdaUpdateWrapper<CourseBankType> updateWrapper = new LambdaUpdateWrapper<CourseBankType>()
                .eq(CourseBankType::getId, req.getId())
                .set(CourseBankType::getDefaultFlag, CourseConst.DefaultBank.DEFAULT.getCode());
        return this.getService().update(updateWrapper);
    }

    @Override
    public List<CourseBankTypeRes> listEnable(CourseBankTypeReq req)
    {
        req.setDisableFlag(SysConst.Flag.NO.getFlag());
        return this.list(req);
    }

    @Override
    public boolean updateDisable(CourseBankTypeReq req)
    {
        CourseBankType typePo = this.getExtendService().getByIdNotNull(req.getId());
        if (typePo.getDisableFlag().equals(req.getDisableFlag())) {
            if (SysConst.Flag.IS.getFlag().equals(req.getDisableFlag())) {
                throw new GlobalException("已禁用");
            } else {
                throw new GlobalException("已启用");
            }
        }
        // 查看是否有默认题库
        if (req.getDisableFlag().equals(SysConst.Flag.IS.getFlag()) && CourseConst.DefaultBank.DEFAULT.getCode().equals(typePo.getDefaultFlag())) {
            throw new GlobalException("课程存在默认题库，无法禁用");
        }
        LambdaUpdateWrapper<CourseBankType> typeUpdate = new LambdaUpdateWrapper<>();
        typeUpdate.eq(CourseBankType::getId, typePo.getId())
                .set(CourseBankType::getDisableFlag, req.getDisableFlag());
        return this.getService().update(typeUpdate);
    }

    @Override
    protected void beforeList(CourseBankTypeReq req)
    {
        if (ObjectUtil.isNull(req.getCourseId())
                && ObjectUtil.isNull(req.getCourseChildId())) {
            throw new GlobalException("参数错误！");
        }
    }

    @Override
    protected void beforeSave(CourseBankTypeReq req)
    {
        // 1、校验课程信息是否存在
        Course coursePo = courseExtendService.getByIdNotNull(req.getCourseId());
        if (!CourseConst.LEVEL_NUM_SECOND.equals(coursePo.getLevelNum())) {
            throw new GlobalException("该课程不支持添加类型信息");
        }
        // 2、类型名称是否重复
        checker.checkNameRepeat(req);
        LambdaQueryWrapper<CourseBankType> typeQuery = new LambdaQueryWrapper<>();
        typeQuery.eq(CourseBankType::getCourseId, req.getCourseId())
                .orderByDesc(CourseBankType::getOrderNum);
        CourseBankType typePo = this.getService().getOne(typeQuery, false);
        req.setOrderNum(ObjectUtil.isNotNull(typePo) ? (typePo.getOrderNum() + 1) : 1);
    }

    @Override
    protected void beforeUpdate(CourseBankTypeReq req)
    {
        // 2、类型名称是否重复
        checker.checkNameRepeat(req);
    }


    @Override
    protected void beforeRemove(List<Long> idList)
    {
        // 查看是否有默认题库
        long defaultAmount = this.getService().count(
                new LambdaQueryWrapper<CourseBankType>()
                        .in(CourseBankType::getId, idList)
                        .eq(CourseBankType::getDefaultFlag, CourseConst.DefaultBank.DEFAULT.getCode()));
        if (defaultAmount > 0L) {
            throw new GlobalException("默认题库无法删除");
        }
        // 题库信息
        long bankAmount = bankService.count(new LambdaQueryWrapper<Bank>().
                in(Bank::getCourseBankTypeId, idList));
        if (bankAmount > 0L) {
            throw new GlobalException("该类型已有题库信息，无法删除");
        }
        // 题库配置规则信息
        long bankRuleAmount = bankRuleService.count(new LambdaQueryWrapper<BankRule>()
                .in(BankRule::getCourseBankTypeId, idList));
        if (bankRuleAmount > 0L) {
            throw new GlobalException("该类型已有选题规则信息，无法删除");
        }
        // 查看是都有对应学员
        long studentAmount = studentCourseService.count(new LambdaQueryWrapper<StudentCourse>()
                .in(StudentCourse::getCourseBankTypeId, idList));
        if (studentAmount > 0L) {
            throw new GlobalException("课程存在学员信息，无法删除");
        }
    }
}
